import hashlib
import logging
import re
import ConfigParser
# List of tags which we want their value to be hashed if "hashing" is True
hash_list = ["ACCTID", "INTU_USERID","owner"];
# List of tags that may contain a sub-string that needs to be hashed
# usually transfers write the account to which the transfer is made in these
# fields.
hash_replace_list = ["NAME", "MEMO", "mEMO","acctMemo"]
typeDecimal = ["MKTVAL", "TRNAMT", "UNITS", "UNITPRICE",
               "TOTAL", "BALAMT", "PARVALUE", "COUPONRT", "MARKDOWN", "MARKUP",
               "COMMISSION", "FEES","AVAILCASH","MARGINBALANCE",
               "SHORTBALANCE","BUYPOWER","INTEREST","FEES","TAXES"
               ]
typeDT = ["DTASOF", "DTPRICEASOF", "DTTRADE", "DTSETTLE", "DTPOSTED",
                "DTSTART", "DTEND", "DTMAT", "DTSERVER", "DTPROFUP",
                ]

reDT = re.compile(r"""(?P<Y>(\d\d|\d{4}))(?P<M>\d{2})(?P<D>\d{2}) # Year, Month, Day
((?P<h>\d{2})(?P<m>\d{2})((?P<s>\d{2})(\.\d+)?)?)?   # Hours, Minutes,seconds,mili
((\[(?P<tzsign>(\+|\-))?(?P<tz>\d{1,2})\:[A-Z]{3,4}\])|[A-Z]{3,4})?       # Time-Zone
$""",re.X)

def expandyear(year):
    """Y2K"""
    if len(year)==2:
        if year>'50':
            year='19'+year
        else:
            year='20'+year
    return year

def svalue(tag,value,language=None,hashing=False):
    if isinstance(value,basestring):
        value=value.replace('"','\\"')
    else:
        value=str(value)
        
    value_type=""
    if tag.upper() in typeDecimal:
        value_type = "^^xsd:decimal"
    elif tag.upper()[0:2]=="DT":
        value_type = "^^xsd:dateTime"
        m= reDT.match(value)
        if not m: raise SyntaxError("Bad date-time %s" % (value))
        if m.group("h"):
            value = "%s-%s-%sT%s:%s:%s"%(
                expandyear(m.group("Y")),m.group("M"),m.group("D"),
                m.group("h"),m.group("m"),m.group("s"))
        else:
            value = "%s-%s-%sT00:00:00"%(
                expandyear(m.group("Y")),m.group("M"),m.group("D"))
        if m.group("tz"):
            if m.group("tzsign"):
                value += m.group("tzsign")
            else:
                value += '+'
            if len(m.group("tz")) ==1:
                value += '0'
            value += m.group("tz")
            value += ":00"
        else:
            import cherrypy
            value+=cherrypy.config.get('tz','')
    elif hashing and tag.upper() in hash_list:
        new_value = hashlib.sha1(value).hexdigest()[:4]
        if isinstance(hashing,ConfigParser.RawConfigParser):
            if not hashing.has_section('hash'):
                hashing.add_section('hash')
            if hashing.has_option('hash',value):
                new_value = hashing.get('hash',value)
            else:
                hashing.set('hash',value,new_value)
        logging.info("Hashing %s to %s"%(value,new_value))
        value=new_value
    elif (tag.upper() in hash_replace_list and 
          isinstance(hashing,ConfigParser.RawConfigParser) and
          hashing.has_section('hash')
          ):
        for old,new in hashing.items('hash'):
            value = value.replace(old,new)
    elif language:
        value = value.decode(language).encode('utf-8')
    return (value,value_type)

def stagvalue(tag,values,language=None,hashing=False):
    if not isinstance(values,list):
        values=[values]
    tag=tag.replace(".","_")
    res=""
    for value in values:
        if isinstance(value,float) or value:
            value,value_type=svalue(tag,value,language,hashing)
            ns = 'ofx' if tag.isupper() else 'a3'
            res+='%s:%s "%s"%s; ' % (ns,tag, value,value_type)
    return res

def sdict(d,language=None,hashing=False):
    if not d: return
    assert isinstance(d,dict)
    res=[]
    for k,v in d.iteritems():
        res.append(stagvalue(t,v,language,hashing))
    return " ".join(res)

def n3secid(uniqueidtype,uniqueid):
        secid='ofx:UNIQUEID "%s" ; ofx:UNIQUEIDTYPE "%s" ;'%(uniqueid,uniqueidtype)
        return secid
        #return 'ofx:SECID [ %s ] ;'%secid

def n3header(fout,version,context=None):
    print >>fout,"""# Generated by %s""" % version
    print >>fout,"""
@prefix ofx: <http://www.w3.org/2000/10/swap/pim/ofx#>.
@prefix ofxh: <http://www.w3.org/2000/10/swap/pim/ofx-headers#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix a3: <http://code.google.com/p/3account/wiki/Schema#>.
"""
    if context:
        print >>fout,"<file://%s>"%context
    else:
        print >>fout,"<>"
